﻿//------------------------------------------------------------------------------
//Author: Christoph van der Fecht
//CodePlex: http://www.codeplex.com/site/users/view/ChristophvdF
//
//Copyright(c) Christoph van der Fecht
//------------------------------------------------------------------------------
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Controls; 
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;


namespace SerienNewsReader.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        /// <summary>
        /// Default value of the window
        /// </summary>
        private const string defaultTitle = "Serien News Reader";

#if (Desktop || Debug)
        /// <summary>
        /// Collection containing all menu entries
        /// </summary>
        private ObservableCollection<MenuItem> menu = default(ObservableCollection<MenuItem>); 
#elif WP
        private ObservableCollection<MenuItem> menu = default(ObservableCollection<MenuItem>);
#endif

        /// <summary>
        /// Title of the main Window
        /// </summary>
        private string windowTitle = defaultTitle;

        /// <summary>
        /// Command to apply the filter
        /// </summary>
        private RelayCommand<string> applyFilterCommand;

        /// <summary>
        /// Command to show the <see cref="Options"/> dialog
        /// </summary>
        private RelayCommand showOptions;

        /// <summary>
        /// Sends the apply message command
        /// </summary>
        /// <param name="criteria">Filter criteria for the command</param>
        private void ApplyFilter(string criteria)
        {
            this.WindowTitle = string.Format("{0} - {1}", defaultTitle, criteria);
            Messenger.Default.Send<string>(criteria);
        }

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            if (IsInDesignMode)
            {
                List<MenuItem> items = new List<MenuItem>();
                for (int menuCounter = 0; menuCounter < 8; menuCounter++)
                {
                    items.Add(new MenuItem()
                    {
                        Header = "Test" + menuCounter
                    });
                }

            }
            else
            {
#if (Desktop || Debug)
                config.Default.SettingsSaving += new System.Configuration.SettingsSavingEventHandler(OnSettingsSaved);
                this.PrepareFilterMenueDesktop(); 
#elif WP
                //regist a event so reload the settings
                this.PrepareFilterMenuPhone();
#endif
            }
        }

        void OnSettingsSaved(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.PrepareFilterMenueDesktop();
        }

        private void PrepareFilterMenuPhone()
        {
            throw new System.NotImplementedException();
        }

        /// <summary>
        /// Pops up the <see cref="Options"/> dialog
        /// </summary>
        private void ShowOptionsDialog()
        {
            Options options = new Options();
            options.ShowDialog();
        }

        /// <summary>
        /// Builds upda the menu entries from the settings file
        /// </summary>
        private void PrepareFilterMenueDesktop()
        {
            List<string> entries = this.ParseMenuEntries();
            List<MenuItem> items = new List<MenuItem>();
            if (entries.Count == 0)
            {
                return;
            }
            else
            {
                entries.Sort();
                foreach (string entry in entries)
                {
                    if (string.IsNullOrEmpty(entry))
                    {
                        continue;
                    }
                    else
                    {
                        MenuItem item = new MenuItem();
                        item.Header = entry;
                        item.Command = this.ApplyFilterCommand;
                        item.CommandParameter = item.Header;
                        items.Add(item);
                        //base.RaisePropertyChanged("Menu");
                    }
                }

                MenuItem allMySeries = new MenuItem();
                allMySeries.Header = "All my series";
                allMySeries.Command = this.ApplyFilterCommand;
                allMySeries.CommandParameter = allMySeries.Header;
                items.Add(allMySeries);

                MenuItem allSeries = new MenuItem();
                allSeries.Header = "All series";
                allSeries.Command = this.ApplyFilterCommand;
                allSeries.CommandParameter = allSeries.Header;
                items.Add(allSeries);

                if (items.Count > 0)
                {
                    this.Menu = new ObservableCollection<MenuItem>(items);
                }
            }
        }

        /// <summary>
        /// Parses the menu entries from the setting file
        /// </summary>
        /// <returns><see cref="List<>"/> of strings containing all names of the series</returns>
        private List<string> ParseMenuEntries()
        {
            return config.Default.Series.Split(';').ToList<string>();

        }

#if (Desktop || Debug)
        /// <summary>
        /// Gets the <see cref="MenuItem"/> objects for the menu
        /// </summary>
        public ObservableCollection<MenuItem> Menu
        {
            get
            {
                return this.menu;
            }
            set
            {
                if (value != null && value != this.menu)
                {
                    this.menu = new ObservableCollection<MenuItem>(value.OrderBy(x => x.Header));
                    base.RaisePropertyChanged("Menu");
                }
            }
        } 
#elif WP
        /// <summary>
        /// Gets the <see cref="MenuItem"/> objects for the menu
        /// </summary>
        public ObservableCollection<MenuItem> Menu
        {
            get
            {
                return this.menu;
            }
            set
            {
                if (value != null && value != this.menu)
                {
                    this.menu = new ObservableCollection<MenuItem>(value.OrderBy(x => x.Header));
                    base.RaisePropertyChanged("Menu");
                }
            }
        }
#endif

        /// <summary>
        /// Gets the command to apply a filter
        /// </summary>
        public RelayCommand<string> ApplyFilterCommand
        {
            get
            {
                if (this.applyFilterCommand == null)
                {
                    this.applyFilterCommand = new RelayCommand<string>(this.ApplyFilter);
                }
                return this.applyFilterCommand;
            }
        }

        /// <summary>
        /// Gets the command to pop up the options dialog
        /// </summary>
        public RelayCommand ShowOptions
        {
            get
            {
                if (this.showOptions == null)
                {
                    this.showOptions = new RelayCommand(this.ShowOptionsDialog);
                }
                return this.showOptions;
            }
        }

        /// <summary>
        /// Gets or sets the title of the main window
        /// </summary>
        public string WindowTitle
        {
            get
            {
                return this.windowTitle;
            }

            set
            {
                if (value != this.windowTitle)
                {
                    this.windowTitle = value;
                    base.RaisePropertyChanged("WindowTitle");
                }
            }
        }

        /// <summary>
        /// Cleans up everything in the view model
        /// </summary>
        public override void Cleanup()
        {
            this.menu = null;

            base.Cleanup();
        }
    }
}